home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Tutorials / ARexx / Host / RexxShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-03  |  7.0 KB  |  329 lines

  1. /****************************************************************************/
  2.  
  3. #include <dos/dosextens.h>
  4. #include <dos/dostags.h>
  5. #include <dos/rdargs.h>
  6.  
  7. #include <exec/execbase.h>
  8.  
  9. #include <rexx/rxslib.h>
  10. #include <rexx/errors.h>
  11.  
  12. #include <clib/rexxsyslib_protos.h>
  13. #include <clib/utility_protos.h>
  14. #include <clib/exec_protos.h>
  15. #include <clib/dos_protos.h>
  16.  
  17. #include <pragmas/rexxsyslib_pragmas.h>
  18. #include <pragmas/utility_pragmas.h>
  19. #include <pragmas/exec_pragmas.h>
  20. #include <pragmas/dos_pragmas.h>
  21.  
  22. #include <string.h>
  23. #include <stdio.h>
  24.  
  25. /****************************************************************************/
  26.  
  27. struct CmdArgs
  28. {
  29.     STRPTR HostName;    /* Name of host to send commands to. */
  30.     STRPTR Extension;    /* Default file name extension. */
  31.     LONG String;        /* Input are short programs rather than
  32.                  * program names.
  33.                  */
  34. };
  35.  
  36. /****************************************************************************/
  37.  
  38.     /* Defined and initialized by compiler startup code. */
  39.  
  40. extern struct Library * SysBase;
  41. extern struct Library * DOSBase;
  42.  
  43.     /* To be initialized by this program. */
  44.  
  45. struct Library * RexxSysBase;
  46. struct Library * UtilityBase;
  47.  
  48. /****************************************************************************/
  49.  
  50. int
  51. main(int argc,char **argv)
  52. {
  53.     struct MsgPort *ReplyPort;
  54.     struct MsgPort *RexxPort;
  55.     struct RexxMsg *RexxMessage;
  56.     struct RDArgs *Args;
  57.     struct CmdArgs Parameters;
  58.     UBYTE Command[256];
  59.     UBYTE HostName[80];
  60.     LONG Len;
  61.     LONG i;
  62.     BOOL Done;
  63.     BOOL Sent;
  64.  
  65.         /* This program requires AmigaOS v2.04 or higher to run. */
  66.  
  67.     if(SysBase->lib_Version < 37)
  68.     {
  69.         printf("This program requires AmigaOS v2.04 or higher to run.\n");
  70.  
  71.         return(RETURN_FAIL);
  72.     }
  73.  
  74.         /* Open the Rexx system library. */
  75.  
  76.     RexxSysBase = OpenLibrary(RXSNAME,0);
  77.  
  78.     if(RexxSysBase == NULL)
  79.     {
  80.         Printf("Error opening %s.\n",RXSNAME);
  81.  
  82.         return(RETURN_FAIL);
  83.     }
  84.  
  85.         /* Open utility.library, we will need it for string
  86.          * comparison and to convert the host name to
  87.          * upper case characters.
  88.          */
  89.  
  90.     UtilityBase = OpenLibrary("utility.library",37);
  91.  
  92.     if(UtilityBase == NULL)
  93.     {
  94.         Printf("Error opening %s v37.\n","utility.library");
  95.  
  96.         CloseLibrary(RexxSysBase);
  97.  
  98.         return(RETURN_FAIL);
  99.     }
  100.  
  101.         /* Create the message reply port. */
  102.  
  103.     ReplyPort = CreateMsgPort();
  104.  
  105.     if(ReplyPort == NULL)
  106.     {
  107.         Printf("Could not create message reply port.\n");
  108.  
  109.         CloseLibrary(RexxSysBase);
  110.         CloseLibrary(UtilityBase);
  111.  
  112.         return(RETURN_FAIL);
  113.     }
  114.  
  115.         /* Clear the command line argument storage. */
  116.  
  117.     Parameters.HostName = NULL;
  118.     Parameters.Extension = NULL;
  119.     Parameters.String = FALSE;
  120.  
  121.         /* Read the command line arguments. */
  122.  
  123.     Args = ReadArgs("HOST,EXTENSION,STRING/S",(LONG *)&Parameters,NULL);
  124.  
  125.     if(Args == NULL)
  126.     {
  127.             /* Print an error message. */
  128.  
  129.         PrintFault(IoErr(),"RexxShell");
  130.  
  131.         DeleteMsgPort(ReplyPort);
  132.  
  133.         CloseLibrary(RexxSysBase);
  134.         CloseLibrary(UtilityBase);
  135.  
  136.         return(RETURN_FAIL);
  137.     }
  138.  
  139.         /* If a default host name was provided, convert
  140.          * it to upper case characters.
  141.          */
  142.  
  143.     if(Parameters.HostName == NULL)
  144.         strcpy(HostName,"REXX");
  145.     else
  146.     {
  147.             /* We will truncate the name if it is
  148.              * longer than 79 characters.
  149.              */
  150.  
  151.         Len = strlen(Parameters.HostName);
  152.  
  153.         if(Len > 79)
  154.             Len = 79;
  155.  
  156.         for(i = 0 ; i < Len ; i++)
  157.             HostName[i] = ToUpper(Parameters.HostName[i]);
  158.  
  159.             /* Provide null-termination. */
  160.  
  161.         HostName[Len] = 0;
  162.     }
  163.  
  164.         /* Print the welcome message. */
  165.  
  166.     Printf("Enter names of ARexx scripts to execute. To quit\n");
  167.     Printf("just enter \"stop\".\n");
  168.  
  169.         /* Show our current parameters. */
  170.  
  171.     Printf("Default host name is \"%s\".\n",HostName);
  172.  
  173.     if(Parameters.Extension == NULL)
  174.         Printf("Default file name extension is \"%s\".\n","REXX");
  175.     else
  176.         Printf("Default file name extension is \"%s\".\n",Parameters.Extension);
  177.  
  178.     if(Parameters.String == FALSE)
  179.         Printf("Input is interpreted as names of commands to execute.\n");
  180.     else
  181.         Printf("Input is interpreted as short Rexx commands.\n");
  182.  
  183.     Done = FALSE;
  184.  
  185.         /* Loop until the user enters "stop" or
  186.          * closes the console window.
  187.          */
  188.  
  189.     do
  190.     {
  191.             /* Show the prompt. */
  192.  
  193.         Printf("RX> ");
  194.         Flush(Output());
  195.  
  196.             /* Read the user input, stop if the console
  197.              * window gets closed.
  198.              */
  199.  
  200.         if(FGets(Input(),Command,sizeof(Command) - 1) == NULL)
  201.             Done = TRUE;
  202.         else
  203.         {
  204.                 /* Chop off the trailing line feed
  205.                  * character if any.
  206.                  */
  207.  
  208.             Len = strlen(Command);
  209.  
  210.             if((Len > 0) && (Command[Len - 1] == '\n'))
  211.                 Command[--Len] = 0;
  212.  
  213.                 /* Stop if the user wants us to stop. */
  214.  
  215.             if(Stricmp(Command,"stop") == 0)
  216.                 Done = TRUE;
  217.         }
  218.  
  219.             /* Should we continue and do we have a
  220.              * command to execute?
  221.              */
  222.  
  223.         if((Done == FALSE) && (Len > 0))
  224.         {
  225.                 /* Set up the RexxMsg we want to use.
  226.                  *
  227.                  * The extension tells the Rexx process how
  228.                  * to construct the name of the file it
  229.                  * is to execute. For example, if the
  230.                  * extension were "demo" and the command
  231.                  * were "test" it would look for a command
  232.                  * file named "test.demo" and if this could
  233.                  * not be found search for "test.rexx".
  234.                  *
  235.                  * The host name tells Rexx which host to
  236.                  * address when it finds a command it does
  237.                  * not know.
  238.                  *
  239.                  * If no extension or host name is provided,
  240.                  * i.e. NULL parameters are given, the
  241.                  * parameters default to "REXX".
  242.                  */
  243.  
  244.             RexxMessage = CreateRexxMsg(ReplyPort,
  245.                 Parameters.Extension,HostName);
  246.  
  247.             if(RexxMessage == NULL)
  248.                 Printf("Error creating rexx message.\n");
  249.             else
  250.             {
  251.                     /* Make the command ready. */
  252.  
  253.                 RexxMessage->rm_Args[0] = CreateArgstring(Command,Len);
  254.  
  255.                 if(RexxMessage->rm_Args[0] == NULL)
  256.                     Printf("Error creating message argument.\n");
  257.                 else
  258.                 {
  259.                         /* Mark the message as a command. */
  260.  
  261.                     RexxMessage->rm_Action = RXCOMM;
  262.  
  263.                         /* The Rexx process can interprete
  264.                          * the message arguments in two different
  265.                          * ways. If the RXFF_STRING flag is not
  266.                          * set and the first character of the
  267.                          * command string is not a quote or
  268.                          * double quote Rexx will try to find
  269.                          * a program matching the command name.
  270.                          * Otherwise, the command will be treated
  271.                          * as a short Rexx program.
  272.                          */
  273.  
  274.                     if(Parameters.String != FALSE)
  275.                         RexxMessage->rm_Action |= RXFF_STRING;
  276.  
  277.                         /* Now try to find the resident process
  278.                          * communications port. We need to
  279.                          * turn off multitasking while we look
  280.                          * for it and send the message.
  281.                          */
  282.  
  283.                     Forbid();
  284.  
  285.                     if(RexxPort = FindPort(RXSDIR))
  286.                     {
  287.                         PutMsg(RexxPort,RexxMessage);
  288.  
  289.                         WaitPort(ReplyPort);
  290.                         GetMsg(ReplyPort);
  291.  
  292.                         Sent = TRUE;
  293.                     }
  294.                     else
  295.                         Sent = FALSE;
  296.  
  297.                     Permit();
  298.  
  299.                         /* Was the message sent to Rexx? */
  300.  
  301.                     if(Sent == FALSE)
  302.                         Printf("Could not send message, REXX host not found.\n");
  303.                     else
  304.                     {
  305.                         Printf("Command \"%s\" has returned with result %ld,%ld\n",
  306.                             Command,RexxMessage->rm_Result1,RexxMessage->rm_Result2);
  307.                     }
  308.  
  309.                     DeleteArgstring(RexxMessage->rm_Args[0]);
  310.                 }
  311.  
  312.                 DeleteRexxMsg(RexxMessage);
  313.             }
  314.         }
  315.     }
  316.     while(Done == FALSE);
  317.  
  318.         /* Clean up. */
  319.  
  320.     FreeArgs(Args);
  321.  
  322.     DeleteMsgPort(ReplyPort);
  323.  
  324.     CloseLibrary(RexxSysBase);
  325.     CloseLibrary(UtilityBase);
  326.  
  327.     return(RETURN_OK);
  328. }
  329.